from fastapi import APIRouter, Depends, Request
from typing import Optional, Any
from sqlalchemy.future import select
from sqlmodel.ext.asyncio.session import AsyncSession
from schemas.common import RETURN
from fastapi_limiter.depends import RateLimiter
import time

from database.mysql import get_async_session
from utils.util import random_num

from core.Log import log_admin_event
from database.mysql import AsyncSessionLocal
from models.admin.system.Sms import sys_sms, EnvetEnum
from extend.Sms import SmsServer
from schemas.user import SMSRequest

router = APIRouter(prefix="/sms", tags=["api-短信管理"])
dataLimit = False

async def check_sms(mobile: str, code: str, event: EnvetEnum):
    few_minutes_ago = time.time() - 300
    state = (
        select(sys_sms)
        .where(sys_sms.mobile == mobile)
        .where(sys_sms.event == event)
        .where(sys_sms.code == code)
        .where(sys_sms.times == 0)
        .where(sys_sms.createtime >= few_minutes_ago)
    )
    async with AsyncSessionLocal() as session:
        try:
            result = await session.exec(state)
            result = result.scalars().first()
            if not result:
                return False
            result.times = 1
            session.add(result)
            await session.commit()
            return True
        except Exception as e:
            log_admin_event(f"check sms error: {str(e)}")
            await session.rollback()
            return False

# 发送短信验证码
@router.post("/send", dependencies=[Depends(RateLimiter(times=2, seconds=5))], response_model=RETURN[Optional[Any]])
async def send_sms(data: SMSRequest, req: Request , session: AsyncSession = Depends(get_async_session)):
    two_minutes_ago = time.time() - 120
    state = (
        select(sys_sms)
        .where(sys_sms.mobile == data.mobile)
        .where(sys_sms.event == data.event)
        .where(sys_sms.times == 0)
        .where(sys_sms.createtime >= two_minutes_ago)
    ) 
    result = await session.exec(state)
    result = result.scalars().first()
    if result:
        return RETURN.fail("发送过于频繁，请稍后再试")
    code = random_num(4)
    isSend = await SmsServer.send_sms(data.mobile, code, data.event)
    if isSend:
        # 入库
        add_sms = sys_sms(
            event=data.event,
            mobile=data.mobile,
            code=code,
            times=0,
            ip=req.client.host
        )
        session.add(add_sms)
        await session.commit()
        return RETURN.success("发送成功")
    return RETURN.fail("发送失败")

# 验证短信
@router.post("/check_sms", response_model=RETURN[Optional[Any]])
async def check(data: SMSRequest, code: str):
    isCheck = await check_sms(data.mobile, code, data.event)
    if isCheck == True:
        return RETURN.success("验证通过")
    return RETURN.fail("验证失败")
